#include "ContextMenuWindow.h"

#include "Widgets/RectangleWidget.h"
#include "Widgets/TextWidget.h"
#include "Widgets/Positioners/VerticalPositionerWidget.h"
#include "Widgets/Mouse/MouseWidget.h"
#include "Widgets/CanvasWidget.h"
#include "PopWindow.h"

RContextMenuWindow::RContextMenuWindow()
{
    HideSystemBorder();

    auto Background=NewWidget<RRectangleWidget>(GetRootWidget());
    Background->Anchor.Fill(GetRootWidget());

    Background->FillColor=SColor::FromHexRGB(0x333333);
    
    Background->BorderSize=1.f;
    Background->BorderColor=SColor::FromHexRGB(0x666666);

    Container= NewWidget<RVerticalPositionerWidget>(GetRootWidget());
    Container->Anchor.Fill(GetRootWidget());
    Container->Spacing=1;

    KeepAliveRectDelegate=TDelegate<SRect>::Create(this,&RContextMenuWindow::GetKeepAliveRect);
}

void RContextMenuWindow::AddItem(const SContextMenuItem &InNewItem)
{
    auto Item=NewWidget<RRectangleWidget>(Container);
    Item->Anchor.HorizontalFill(Container);
    Item->Height=GetItemHeight();
    Item->FillColor=SColor::FromHexRGB(0x333333);

    auto Text=NewWidget<RTextWidget>(Item);
    Text->Anchor.Fill(Item);
    Text->Text=InNewItem.Text;
    
    //add a triangle if has sub menu
    if(!InNewItem.SubMenus.Empty())
    {
        auto Arrow=NewWidget<RCanvasWidget>(Item);
        Arrow->AddTriangle(SVec2(0,0),SVec2(10,7.5),SVec2(0,15),SColor::White);
        Arrow->Width=15;
        Arrow->Height=15;
        Arrow->Anchor.RightReference=Item;
        Arrow->Anchor.RightOffset=2;
        Arrow->Anchor.VerticalCenterReference=Item;
    }


    auto Mouse =NewWidget<RMouseWidget>(Item);
    Mouse->Anchor.Fill(Item);
    if(InNewItem.OnClicked.IsBound())
    {
        Mouse->OnClicked.BindLambda(
            [InNewItem](const SMouseButtonEvent &){
                InNewItem.OnClicked.ExecuteIfBound();
                return true;
            }
        );
    }

    RRectangleWidgetWeakPtr ItemWeakPtr=Item;
    uint32_t ItemIndex= Container->GetSubWidgetNum()-1;
    Mouse->OnEntered.BindLambda([InNewItem,this,ItemIndex,ItemWeakPtr](){
        ItemWeakPtr->FillColor=SColor::Green;

        //remove former sub menu
        if(CurrentSubMenu &&!CurrentSubMenu->IsClosed() )
        {
            CurrentSubMenu->GetParentWindow()->CloseAttachedPopWindow();
            CurrentSubMenu=nullptr;
        }

        CurrentItemIndex= ItemIndex;
        //try create new sub menu
        if(!InNewItem.SubMenus.Empty())
        {
            SIntPoint NewWindowPosition;
            NewWindowPosition.X=GetWindowPosition().X+GetWindowSize().X-2;
            NewWindowPosition.Y=GetWindowPosition().Y+GetItemHeight()*ItemIndex;

            CurrentSubMenu=NewObject<RContextMenuWindow>(); 
            //CurrentSubMenu=CreatePopWindow(this,StaticClass());
            CurrentSubMenu->SetWindowPosition(NewWindowPosition);
            CurrentSubMenu->SetWindowSize(SIntPoint(200,GetItemHeight()*InNewItem.SubMenus.Num()));
            AttchCurrentSubMenu(); //use a function, just for skip MSVC compile error

            for(auto &Item:InNewItem.SubMenus)
            {
                CurrentSubMenu->AddItem(Item);
            }

            CurrentSubMenu->Show();
        }
    }
    );

    Mouse->OnExited.BindLambda([ItemWeakPtr](){
        ItemWeakPtr->FillColor=SColor::FromHexRGB(0x333333);
    });

}

uint32_t RContextMenuWindow::GetItemCount()
{
    return Container->GetSubWidgetNum();
}

void RContextMenuWindow::AttchCurrentSubMenu()
{
    this->AttachPopWindow(CurrentSubMenu
        ,KeepAliveRectDelegate
    );
}

RWindowPtr RContextMenuWindow::CreateContextMenu(
    RWindowPtr ParentWindow 
    ,const TVector<SContextMenuItem> & InItems
    , const SIntPoint &InWindowPosition)
{
    auto Window=RContextMenuWindowPtr(CreatePopWindow(ParentWindow,StaticClass()));
    Window->SetWindowPosition(InWindowPosition);
    Window->SetWindowSize(SIntPoint(200,GetItemHeight()*InItems.size()));
    for(auto &Item:InItems)
    {
        Window->AddItem(Item);
    } 

    return Window;
}

RWindowPtr RContextMenuWindow::CreateContextMenuAtMouse(
    RWindowPtr ParentWindow 
    ,const TVector<SContextMenuItem> &InItems)
{
    return CreateContextMenu(ParentWindow, InItems,SMouseButtonEvent::GetMosuePositionOnScreen());
}
